package com.nt.train.util;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 演示jdk1.8新特性实例
 * http://t.zoukankan.com/envythink-p-12871849.html
 * @author hlf
 * @version 1.0
 * @date 2022/8/10 8:37
 */
public class ExampleUtil {

//    public static void main(String[] args) {
//        List<String> strings = Arrays.asList("who","what","when","why","which","");
//        List<String> filterd = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
//        System.out.println(filterd);
//    }

    /**
     * 1、forEach 循环
     */
    public static void  doforEach(){
        List<String> stringList = Arrays.asList("who","what","when","why","which");

        // 方式一：JDK1.8之前的循环方式
        for(String string:stringList){
            System.out.println(string);
        }

        // 方式二：使用Stream的forEach方法
        stringList.stream().forEach(e -> System.out.println(e));

        // 方式三：方式二的简化形式，因为方法引用也属于函数式接口，因此Lambda表达式可以用方法引用来代替
        stringList.stream().forEach(System.out::println);

    }

    /**
     *2、filter 过滤
     */
    public static void  doFilter(){
        List<String> stringList = Arrays.asList("","welcome","","to","visit","my","","website");
        long count = stringList.stream().filter(e -> e.isEmpty()).count();
        System.out.println(count);

    }

    /**
     * 3、map 映射
     */
    public static void  doMap(){
        List<Integer> integerList = Arrays.asList(2,3,4,5,6);
        List<Integer> integers = integerList.stream().map(i->i*i).collect(Collectors.toList());
        integerList.stream().forEach(System.out::println);
    }

    /**
     * 4、flatMap 映射
     */
    public static void  doflatMap(){
//        //jdk1.8之前的合并方式
//        List<String> fruitList = Arrays.asList("banana","orange","watermelon");
//        List<String> vegetableList = Arrays.asList("kale","leek","carrot");
//        List<String> transportList = Arrays.asList("car","bike","train");
//
//        //将多个元素合成一个复合类型集合，元素类型List<String>
//        List<List<String>> lists = new ArrayList<>();
//        lists.add(fruitList);
//        lists.add(vegetableList);
//        lists.add(transportList);
//
//        //将多个元素合成一个单一类型集合，元素类型String
//        List<String> newList = new ArrayList<>();
//        for(List<String> list:lists){
//            for(String item:list){
//                newList.add(item);
//            }
//        }
        //使用jdk1.8提供的stream流，同时辅助of、collect和flatMap就可以直接进行转换：
        List<String> fruitList = Arrays.asList("banana","orange","watermelon");
        List<String> vegetableList = Arrays.asList("kale","leek","carrot");
        List<String> transportList = Arrays.asList("car","bike","train");

        //将多个元素合成一个复合类型集合，元素类型List<String>
        List<List<String>> lists = Stream.of(fruitList,vegetableList,transportList).collect(Collectors.toList());

        //将多个元素合成一个单一类型集合，元素类型String
        List<String> flatMap = Stream.of(fruitList,vegetableList,transportList)
                .flatMap(list ->list.stream())
                .collect(Collectors.toList());
        System.out.println(flatMap);

    }

    /**
     * 5、sorted 排序
     */
    public static void  doSorted (){
        List<String> stringList = Arrays.asList("c","a","f","d","b","e");
        stringList.stream().sorted((s1,s2) -> s1.compareTo(s2)).forEach(System.out::println);
       // 再举个例子，对10个随机数进行排序并输出：
        Random random = new Random();
        random.ints().limit(10).sorted().forEach(System.out::println);

    }

    /**
     * 6、distinct 去除重复
     */
    public static void  doDistinct(){
        //distinct方法用于去除流中重复的元素，缺点就是不能设置去重的条件。举个例子来说：
        List<String> stringList = Arrays.asList("do","what","you","want","to","do","and","do","it");
        stringList.stream().distinct().forEach(System.out::println);

    }
    //7、of 生成Stream对象
    public static void  doOf(){
        //of方法用于生成Stream对象，注意它是Stream对象的方法。举个例子来说：
        Stream<Object> objectStream= Stream.of("do","what","you","want","to","do","and","do","it");
        objectStream.forEach(System.out::println);

    }

    //8、count 计算总数
    public static void  doCount(){
        //count方法用于计算流中元素的总数。举个例子来说：
        Stream<Object> objectStream = Stream.of("do","what","you","want","to","do","and","do","it");
        long count = objectStream.count();
        System.out.println(count);

    }
    //9、min和max 最小/最大
    public static void  doMaxOfmin(){
       // min/max方法用于返回流中那个元素最小（最大）的，注意返回的是一个Optional对象。举个例子来说：
        List<String> integerList = Arrays.asList("1","2","3","4","5","6","7");
        Optional<String> optionalInteger = integerList.stream().max((a, b) -> a.compareTo(b));
        String result =  optionalInteger.get();
        System.out.println(result);  //结果为7

    }
    //10、collect
    public static void  doCollect(){
        List<String> stringList= Arrays.asList("do","what","you","want","to","do","and","do","it");
        //Stream转Collection
        stringList.stream().collect(Collectors.toList());
        //Stream转Object[]数组
        Object[] objects = stringList.stream().toArray();

    }
    //11、concat
    public static void  doConcat(){
       // concat方法用于合并流对象，注意这时Stream对象的方法。举个例子来说：

        List<String> fruitList = Arrays.asList("banana","orange","watermelon");
        List<String> vegetableList = Arrays.asList("kale","leek","carrot");

        Stream<String> stringStream = Stream.concat(fruitList.stream(),vegetableList.stream());
        stringStream.forEach(System.out::println);

    }
    //12、skip和limit
    public static void skipTest(long n){
        Stream<Integer> integerStream = Stream.of(1,2,3,4,5,6);
        integerStream.skip(n).forEach(System.out::println);
    }

    public static void limitTest(long n){
        Stream<Integer> integerStream = Stream.of(1,2,3,4,5,6);
        integerStream.limit(n).forEach(System.out::println);
    }
     //13、并行（parallel）执行
    public static void  doParallel(){
        List<String> stringList= Arrays.asList("a","","b","","e","","c","","f");
        //获取空字符串的数量
        long count = stringList.parallelStream().filter(string -> string.isEmpty()).count();
        System.out.println(count);  // 4
    }
    //14、anyMatch、allMatch和noneMatch
    public static void  anyMatch(){
       // anyMatch方法用于判断流中是否存在满足特定条件的元素，返回类型是boolean类型。（只要有一个条件满足即返回true）
        List<String> stringList = Arrays.asList("hello","the","fruit","name","is","banana");
        Boolean result = stringList.parallelStream().anyMatch(item -> item.equals("name"));
        System.out.println(result);  // true

       // allMatch方法用于判断流中是否存在满足特定条件的元素，返回类型是boolean类型。（必须全部满足才会返回true）
        List<String> stringList2 = Arrays.asList("hello","the","fruit","name","is","banana");
        Boolean result2 = stringList2.parallelStream().allMatch(item -> item.equals("name"));
        System.out.println(result2);  // false
        //noneMatch方法用于判断流中是否存在满足特定条件的元素，返回类型是boolean类型。（全都不满足才会返回true）

        List<String> stringList3 = Arrays.asList("hello","the","fruit","name","is","banana");
        Boolean result3 = stringList3.parallelStream().noneMatch(item -> item.equals("name"));
        System.out.println(result3);  // false
        //上面这个例子就是因为有一个满足条件就返回了false。

    }
    //15、reduce
    public static void  doReduce(){
       // educe的意思是减少，而Stream中reduce方法就是用于实现这个目的，它根据一定的规则将Stream中的元素进行计算后返回一个唯一的值。举个例子来说：
        Stream<String> stringStream = Stream.of("my","name","is","envy");
        Optional<String> stringOptional = stringStream.reduce((before, after) -> before+"、"+after);
        stringOptional.ifPresent(System.out::println);  // my、name、is、envy

    }
    //16、findFirst和findAny
    public static void  findFirst(){
       // findFirst方法用于返回list列表中第一个元素，注意如果元素不存在则抛异常。举个例子来说：
        List<String> stringList = Arrays.asList("do","what","you","want","to","do","and","do","it");
        Optional<String> result = stringList.parallelStream().findFirst();
        System.out.println(result.get());  // do

       // 注意若Optional为空，则get方法会抛出异常，但是你可以使用orElse(defaultVal)；或使用orElseGet(() -> {// doSomething; return defaultVal;});来返回默认值。举个例子来说：

//            List<String> stringList = Arrays.asList();
//            Optional<String> result = stringList.parallelStream().findFirst();
//            System.out.println(result.orElse("没有元素"));  // 没有元素
//
//            List<String> stringList = Arrays.asList();
//            Optional<String> result = stringList.parallelStream().findFirst();
//            System.out.println(result.orElseGet(() ->{return "没有元素";}));  // 没有元素

    }
    //17、summaryStatistics统计
    public static void  summaryStatistics(){
        //summaryStatistics方法用于产生统计结果的收集器，举个例子来说：
        List<Integer> integerList = Arrays.asList(3,2,3,5,6,8,9);
        IntSummaryStatistics result = integerList.stream().mapToInt((x)->x).summaryStatistics();
        System.out.println("列表中最大的数："+result.getMax());
        System.out.println("列表中最小的数："+result.getMin());
        System.out.println("列表中所有数之和："+result.getSum());
        System.out.println("列表中所有数的平均数："+result.getAverage());
        System.out.println("列表中元素的个数："+result.getCount());

    }
    //18、Joining集合元素的拼接
    public static void  Joining(){
       // 合元素的拼接，其实就是指定分隔符将列表中的元素合并成一个字符串，注意joining方法是存在于Collectors中的。举个例子来说：

        List<String> stringList = Arrays.asList("my","name","is");
        System.out.println(stringList);  // [my, name, is]

        String result = stringList.stream().collect(Collectors.joining(","));
        System.out.println(result);  // my,name,is

        String newString = Stream.of("I","come","from bei").collect(
                Collectors.collectingAndThen(
                        Collectors.joining(","),x-> x+"jing"));
        System.out.println(newString);  // I,come,from beijing

    }
    public static void  forEach(){

    }
}
